001    /**
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: Nov 30, 2002
005     * Time: 7:49:41 PM
006     */
007    
008    package EVolve.visualization.XYViz.ValValViz;
009    
010    import EVolve.visualization.*;
011    import EVolve.visualization.Dimension;
012    import EVolve.Scene;
013    import EVolve.util.*;
014    import EVolve.util.equators.*;
015    import EVolve.util.equators.Set;
016    import EVolve.util.painters.RandomPainter;
017    import EVolve.data.*;
018    import javax.swing.*;
019    import java.util.*;
020    import java.awt.event.*;
021    import java.awt.*;
022    
023    public class DotplotViz extends ValueValueVisualization {
024        private JTextField textInterval,textMatch, textBegin,textEnd;
025        private DataTrace trace;
026        private long event;
027        private JComboBox comboEquator;
028        private Equator[] equatorList;
029        private float percent;
030        private Equator selectedEquator;
031        private JMenuItem itemSelectX, itemSelectTimeFrame;
032        private static JMenuItem selectionMenu[] = null;
033        private static int SELECT_OPTION = 0x0011;
034        private JLabel toEventNo;
035    
036    
037        public DotplotViz() {
038            super();
039    
040            beginCall = 0;
041            endCall = 300;
042            interval = 10;
043            percent = 100;
044    
045    
046            equatorList = new Equator[2];
047            equatorList[0] = new OrderedEquator();
048            equatorList[1] = new UnorderedEquator();
049            selectedEquator = null;
050        }
051    
052        public Dimension[] createDimension() {
053            Dimension [] returnDimension = new Dimension[2];
054    
055            xAxis = new ValueDimension();
056            entityIdFilter = new ReferenceDimension();
057    
058            returnDimension[0] = xAxis;
059            returnDimension[1] = entityIdFilter;
060    
061            return returnDimension;
062        }
063    
064        public void autoUpdateConfiguration(HashMap config) {
065            super.autoUpdateConfiguration(config);
066            if (config.get("Match")!=null) {
067                percent = ((Float)(config.get("Match"))).floatValue();
068            }
069            if (config.get("Options")!=null) {
070                String equatorName = (String)config.get("Options");
071                for (int i=0; i<equatorList.length; i++)
072                    if (equatorList[i].getName().equals(equatorName)) {
073                        selectedEquator = equatorList[i];
074                        comboEquator.setSelectedIndex(i);
075                        break;
076                    }
077            }
078            textInterval.setText(String.valueOf(interval));
079            textMatch.setText(String.valueOf(percent));
080            textBegin.setText(String.valueOf(beginCall));
081            textEnd.setText(String.valueOf(endCall));
082        }
083    
084        protected void updateConfiguration() {
085    
086            selectedEquator = equatorList[comboEquator.getSelectedIndex()];
087    
088            try {
089                if (autoInterval != -1) {
090                    interval = autoInterval;
091                    autoInterval = -1;
092                } else {
093                    interval = Integer.parseInt(textInterval.getText());
094                    percent = Float.parseFloat(textMatch.getText());
095                    if ((percent>100)||(percent < 0)) {
096                        Scene.showErrorMessage("Match percent must be between 0 and 100.");
097                        configure();
098                    }
099                    textInterval.setText(String.valueOf(interval));
100                    textMatch.setText(String.valueOf(percent));
101                }
102    
103                beginCall = Integer.parseInt(textBegin.getText());
104                endCall = Integer.parseInt(textEnd.getText());
105                selectedEquator.setInterval(interval);
106                selectedEquator.setMatch(percent);
107    
108                canvas.setName(entityIdFilter.getName(), entityIdFilter.getName());
109                super.updateConfiguration();
110            } catch (NumberFormatException e) {
111                Scene.showErrorMessage("Interval, begin call and end call must be an integer and smaller than "+Integer.MAX_VALUE+".");
112                configure();
113            };
114    
115        }
116    
117        public HashMap getCurrentConfigure() {
118            HashMap configure = super.getCurrentConfigure();
119    
120            configure.put("Interval", new Integer(interval));
121            configure.put("BeginCall", new Long(beginCall));
122            configure.put("EndCall", new Long(endCall));
123            configure.put("Match", new Float(percent));
124            configure.put("Options", selectedEquator.getName());
125    
126            return configure;
127        }
128    
129        public void preVisualize() {
130            image = new AutoImage();
131            trace = selectedEquator.initialDataTrace(interval, Scene.getDataManager().getEntity()[entityIdFilter.getDataFilter().getTargetType()].size());
132            event = 0;
133            getSelection();
134            installPainter();
135            super.preVisualize();
136        }
137    
138        protected void receiveElement(Element element) {
139            if (element.isOptional()) return;
140    
141            long traceId = entityIdFilter.getField(element);
142            long no = xAxis.getField(element) - 1;
143    
144            countEvents(no);
145            if ((no < beginCall)||(no > endCall)) {
146                return;
147            }
148    
149            event++;
150            trace.updateTrace(traceId);
151    
152            ArrayList data = trace.getTrace();
153    
154            if ((event%interval == 0)||(event-endCall==1)) {
155                int size = data.size() - 1;
156                for (int i=size+1; i>1; i--) {
157                    Set set1 = (Set)data.get(size);
158                    Set set2 = (Set)data.get(i-2);
159                    if (selectedEquator.isEqual(set1,set2)) {
160                        painter.paint(image,i-2,size,set1.getHashValue());
161                        painter.paint(image,size,i-2,set1.getHashValue());
162                    }
163                }
164                if (size>=0) {
165                    painter.paint(image,size,size,((Set)data.get(size)).getHashValue());
166                    image.setColor(size,size,Color.black);
167                }
168            }
169        }
170    
171        public void visualize() {
172            canvas.setName("Time - " + xAxis.getDataFilter().getName() + " (" + event +" events)", "Time - " + xAxis.getDataFilter().getName() + " (" + event + " events)");
173            sort();
174        }
175    
176        protected void mouseMove(int x,int y) {
177            if (interval > 1) return;
178    
179            int X = canvas.getImageX(x);
180            int Y = canvas.getImageY(y);
181            int index = X < Y ? X : Y;
182            if ((index >= 0) && (trace!=null) && (index < trace.size())) {
183                int mappedId = (int)((Set)trace.getTrace().get(index)).getElement(0);
184                Entity entity = entityIdFilter.getEntityFromInt(mappedId);
185                if (shift_pressed && (image.getSortedColor(null,null,X,Y)==null))
186                    Scene.setStatus("  ");
187                else
188                    Scene.setStatus(entity.getName());
189            } else {
190                Scene.setStatus(" ");
191            }
192        }
193    
194        public void makeSelection() {
195            ArrayList idList = new ArrayList();
196    
197            int x1 = canvas.getStartX();
198            int x2 = canvas.getEndX();
199    
200            if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
201                Scene.showErrorMessage("The active data source used currently is different from \n" +
202                                       "this visualization, please choose \"" +
203                                       Scene.getDataSourceManager().getUsedDataSourceName(dataSourceId)+"\".");
204                return;
205            }
206    
207            if (((x1<0)&&(x2<0)) || ((x1>=trace.getTrace().size())&&(x2>=trace.getTrace().size())))
208               return;
209    
210            if (x1 < 0) x1 = 0;
211            if (x2 >= trace.getTrace().size()) x2 = trace.getTrace().size()-1;
212    
213            Set unionSet = ((Set)(trace.getTrace().get(x1)));
214            for (int i=x1+1; i<=x2; i++) {
215                Set next = ((Set)(trace.getTrace().get(i)));
216                unionSet = unionSet.union(next);
217            }
218    
219            for (int i=0; i<unionSet.size(); i++) {
220                if (unionSet.getEntityId(i)!=-1)
221                    idList.add(new Long(unionSet.getEntityId(i)));
222            }
223    
224            int selection[] = null;
225            if ((SELECT_OPTION & 0x00f0) == SELECT_OCCURRED_ENTITIES) {
226                selection = new int[idList.size()];
227                for (int i=0; i<selection.length; i++)
228                    selection[i] = ((Long)idList.get(i)).intValue();
229            } else {
230                selection = new int[entityIdFilter.getEntityNumber()];
231                for (int i=0; i<selection.length; i++)
232                    selection[i] = i;
233            }
234    
235    
236            long start = ((long[])timeMap.get(((int)(x1+beginCall/interval))))[1];
237            long end;
238            if (x1==x2) {
239                if (x1+1>trace.getTrace().size()-1)
240                    end = Long.MAX_VALUE;
241                else {
242                    end = ((long[])timeMap.get((int)(x1+1+beginCall/interval)))[1]-1;
243                }
244            } else {
245                end = ((long[])timeMap.get(((int)(x2+beginCall/interval))))[1];
246            }
247            if ((SELECT_OPTION & 0x000f) == 0x0000) {
248                start = 0;
249                end = Long.MAX_VALUE;
250            }
251            entityIdFilter.selectComparator(1);
252            entityIdFilter.makeSelection(subjectDefinition.getType(),selection,start,end, timeMap);
253        }
254    
255        protected JPanel createConfigurationPanel() {
256            JPanel returnVal = new JPanel(new GridLayout(1, 1, 5, 5));
257            JPanel panelEvent = new JPanel(new GridLayout(2,2));
258            JPanel equatorBox = new JPanel(new GridLayout(1,2));
259    
260            Box panelBottom = new Box(BoxLayout.Y_AXIS);
261            returnVal.add(panelBottom);
262    
263            textBegin = new JTextField(String.valueOf(beginCall));
264            textEnd = new JTextField(String.valueOf(endCall));
265            panelEvent.add(new JLabel("From Event No:"));
266            panelEvent.add(textBegin);
267    
268            toEventNo = new JLabel("To Event No:");
269            panelEvent.add(toEventNo);
270            panelEvent.add(textEnd);
271            panelBottom.add(panelEvent);
272    
273            comboEquator = new JComboBox();
274            for (int i=0; i<equatorList.length; i++)
275                comboEquator.addItem(equatorList[i].getName());
276            comboEquator.addActionListener(new ActionListener() {
277                public void actionPerformed(ActionEvent e) {
278                    textInterval.setText(String.valueOf(equatorList[comboEquator.getSelectedIndex()].getInterval()));
279                    textMatch.setText(String.valueOf(equatorList[comboEquator.getSelectedIndex()].getMatch()));
280                }
281            });
282    
283            equatorBox.add(new JLabel("Equator:"));
284            equatorBox.add(comboEquator);
285            panelBottom.add(equatorBox);
286    
287            JPanel panelEquator = new JPanel(new GridLayout(2,2));
288    
289            textInterval = new JTextField(String.valueOf(interval));
290            textMatch = new JTextField(String.valueOf(percent));
291    
292            panelEquator.add(new JLabel("Interval:"));
293            panelEquator.add(textInterval);
294            panelEquator.add(new JLabel("Match:"));
295            panelEquator.add(textMatch);
296    
297            panelBottom.add(panelEquator);
298    
299            return returnVal;
300        }
301    
302        protected void installPainter() {
303            painter = new RandomPainter();
304        }
305    
306        public JMenuItem[] createSelectionMenuItem() {
307            if (selectionMenu != null) return selectionMenu;
308    
309            itemSelectTimeFrame = new JCheckBoxMenuItem("Time Frame");
310            itemSelectTimeFrame.setMnemonic(KeyEvent.VK_T);
311            itemSelectTimeFrame.addActionListener(new ActionListener() {
312                public void actionPerformed(ActionEvent e) {
313                    boolean selected = itemSelectTimeFrame.isSelected();
314                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME);
315                }
316            });
317            itemSelectTimeFrame.setSelected(true);
318    
319            itemSelectX = new JCheckBoxMenuItem("Occurred Entitiies");
320            itemSelectX.setMnemonic(KeyEvent.VK_O);
321            itemSelectX.addActionListener(new ActionListener() {
322                public void actionPerformed(ActionEvent e) {
323                    boolean selected = itemSelectX.isSelected();
324                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
325                }
326            });
327            itemSelectX.setSelected(true);
328    
329            selectionMenu = new JMenuItem[2];
330            selectionMenu[0] = itemSelectTimeFrame;
331            selectionMenu[1] = itemSelectX;
332    
333            return selectionMenu;
334        }
335    
336        protected void updateComboSubject() {
337            super.updateComboSubject();
338            String range = String.valueOf(Scene.getDataManager().getDataSource().getNumberOfEvents(elementDefinition[comboSubject.getSelectedIndex()].getName()));
339            toEventNo.setText("To Event No:("+range+")");
340        }
341    
342        public Object clone() {
343            DotplotViz o = (DotplotViz)super.clone();
344            o.dimension[0] = o.xAxis;
345            o.dimension[1] = o.entityIdFilter;
346            o.trace = (trace == null) ? null : (DataTrace)trace.clone();
347            o.createDialog();
348            o.createMenu();
349    
350            return o;
351        }
352    }